#include "quetelet_index_main.h"
#include "ui_quetelet_index_main.h"
#include <QFileDialog>
#include "struct.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include "quickcalculation.h"
#include <QStandardItemModel>
#include <QMessageBox>
#include <QCoreApplication>

using namespace std;

Quetelet_Index_Main::Quetelet_Index_Main(QWidget *parent) :
    //hide minimize/maximaze and X button in window
    QMainWindow(parent, Qt::CustomizeWindowHint),
    ui(new Ui::Quetelet_Index_Main)
{
    ui->setupUi(this);
    CTtable = new CreateTable();
    //Set tab index to 0. This is the starting tab page when the app is opened
    ui->MainTab->setCurrentIndex(0);
    //When the Help button is clicked the help window opens
    connect(ui->BT_Help, SIGNAL(clicked()), this, SLOT(OpenHelpWindow()));
    HelpWindow = new Help();
}

Quetelet_Index_Main::~Quetelet_Index_Main()
{
    delete ui;
    delete CTtable;
    delete HelpWindow;
}


void Quetelet_Index_Main::on_BT_OpenFile_clicked()
{
    //Gives te option to open a txt file(input values to make a table) or a qit file (open a saved table)
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),"", tr("Text-Files (*.txt);;Quetelet-Index Tables (*.qit)"));
    QFile file(fileName);
    if(!file.open(QIODevice::ReadOnly))
    {
        //File not found/File read error
        QMessageBox::information(0,"error",file.errorString());
    }
    QString qsReadData;
    //start reading a line (this is the first in this case)
    qsReadData = file.readLine();
    //Indexof checks if string exsists in the datastring, ifso, it returns the number of the index where the string is, ifnot it returns -1
    if(qsReadData.indexOf("qit") != -1)
    {
        file.close();
        //Opens saved table in the application for viewing
        ui->TB_CreateTable->setModel(CTtable->OpenTable(fileName, this));
    }
    else
    {
        //Set weight input value
        ui->LE_CreateTableInputWeight->setText(qsReadData);
        //Start reading the next line
        qsReadData = file.readLine();
        //Set lenght input value
        ui->LE_CreateTableInputLenght->setText(qsReadData);
        qsReadData = file.readLine();
        //Set steps input value
        ui->LE_CreateTableInputSteps->setText(qsReadData);
        qsReadData = file.readLine();
        //Set end weight input value
        ui->LE_CreateTableInputEndWeight->setText(qsReadData);
        file.close();
    }
}

//Function to save a table wen the save button is clicked
void Quetelet_Index_Main::on_BT_SaveTable_clicked()
{
    //Table is saved in the file type "qit"
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),"", tr("Quetelet-Index Tables (*.qit)"));
    QFile file(fileName);
    //Create abstract interface for model item classes. In this case the table.
    QAbstractItemModel *model = ui->TB_CreateTable->model();
    QModelIndex iIndex = model->index(0, 0);
    //Get data from model on iIndex (0,0)
    int iTableWeight = model->data(iIndex, Qt::DisplayRole).toInt();
    //Go to the next index coordinate
    iIndex = model->index(0, 1);
    //Get data from model on iIndex (0,1)
    float fTableLength = model->data(iIndex, Qt::DisplayRole).toFloat();
    iIndex = model->index(1, 0);
    //Get data from model on iIndex (1,0)
    int iTableSteps = (model->data(iIndex, Qt::DisplayRole).toInt() - iTableWeight);
    iIndex = model->index(model->rowCount()-1, 0);
    //Get data from model on iIndex (-1,0)
    int iTableEndWeight = model->data(iIndex, Qt::DisplayRole).toInt();
    if(!file.open(QIODevice::ReadWrite))
    {
        //File not found/Can not open error
        QMessageBox::information(0,"error",file.errorString()); //error
    }
    file.write("qit\n");
    //Set weight values to string
    file.write(QString::number(iTableWeight).toStdString().c_str());
    file.write("\n");
    //Set lenght values to string
    file.write(QString::number(fTableLength).toStdString().c_str());
    file.write("\n");
    //Set steps values to string
    file.write(QString::number(iTableSteps).toStdString().c_str());
    file.write("\n");
    //set endweight values to string
    file.write(QString::number(iTableEndWeight).toStdString().c_str());
    file.write("\n");

    file.close();
}

//Function to set labels when QuickcalcResult is clicked
void Quetelet_Index_Main::on_BT_QuickCalcResult_clicked()
{
    Set_Quick_Result_Labels();
    //ui->L_IncorrectInputWeightQuickCalcWeight->hide(); //Show incorrect weight input label
    //ui->L_IncorrectInputWeightQuickCalcLenght->hide(); //Show incorrect lenght input label
    //Convert weight input string to interger
    int iWeightInput = ui->LE_QuickCalcWeightInput->text().toInt();
    //Convert lenght input string to float
    float fLenghtInput = ui->LE_QuickCalcLenghtInput->text().toFloat();

    if(!check(iWeightInput, fLenghtInput, 0))
    {
        return;
    }

    QuickCalculation *Qcalc = new QuickCalculation();
    struct UserData *Data = new struct UserData();
    Data->flenght = fLenghtInput;
    Data->iweight = iWeightInput;
    float fQResult = Qcalc->QueteletIndexCalculation(Data);

    QString QsQResult = QString::number(fQResult);
    //Set lable text with the quetelet index result
    ui->L_QuickCalcQueteletIndexResult->setText(QsQResult);
    //Label changes to black color with no border
    ui->L_QuickCalcQueteletIndexResult->setStyleSheet("QLabel { color : black; border : none;}");
    //Set lable text with the weinght status value
    ui->L_QuickCalcWeightStatusResult->setText(Qcalc->ConvertQueteletIndexToString(fQResult));
    //Label changes to black color with no border
    ui->L_QuickCalcWeightStatusResult->setStyleSheet("QLabel { color : black; border : none;}");
    delete Data;
    delete Qcalc;
}

void Quetelet_Index_Main::on_BT_QuickCalcReset_clicked()
{
    Set_Quick_Result_Labels();
}


bool Quetelet_Index_Main::check(int iWeight, float fLength, int iSteps, int iEndweight, int Modus)
{
    bool good = true;

    good = check(iWeight, fLength, Modus);

    //If iSteps value is less then the minimum or iSteps value is higher then maximum the incorrect label is set
    if(iSteps < MIN_STEPS || iSteps > MAX_STEPS )

        ui->LE_CreateStepsInputIncorrect->show(); //show label if  steps input in the create table function is incorrect


    if(iEndweight < MIN_ENDWEIGHT || iEndweight > MAX_ENDWEIGHT)

        ui->LE_CreateEndWeightInputIncorrect->show(); //show label if  endweight input in the create table function is incorrect


    return good;
}

bool Quetelet_Index_Main::check(int iWeight, float fLength, int Modus)
{
    bool good = true;

    if(iWeight < MINWEIGHT_KG || iWeight > MAXWEIGHT_KG)
    {
        if(Modus < 1)
        {
            Set_Quick_Result_Labels();
            ui->L_IncorrectInputWeightQuickCalcWeight->show(); //show label if weight input in the quick calculation function is incorrect
        }
        else
            ui->LE_CreateWeightInputIncorrect->show(); //show label if  weight input in the create table function is incorrect
        good = false;
    }

    if(fLength < MINLENGHT_M || fLength >= MAXLENGHT_M)
    {
        if(Modus < 1)
        {
            Set_Quick_Result_Labels();
            ui->L_IncorrectInputWeightQuickCalcLenght->show(); //show label if lenght input the quick calculation function is incorrect
        }
        else
            ui->LE_CreateLengthInputIncorrect->show(); //show label if  lenght input in the create table function is incorrect
        good = false;
    }
    return good;
}

void Quetelet_Index_Main::on_BT_CreateTable_clicked()
{
    bool wrong = false;
    Set_Create_Table_Incorrect_Labels();
    {
        if(!check(ui->LE_CreateTableInputWeight->text().toInt(), ui->LE_CreateTableInputLenght->text().toFloat(), ui->LE_CreateTableInputSteps->text().toInt(), ui->LE_CreateTableInputEndWeight->text().toInt(), 1))
        {
            wrong = true;
        }
        if(ui->LE_CreateTableInputWeight->text().toInt() >= ui->LE_CreateTableInputEndWeight->text().toInt() || ui->LE_CreateTableInputEndWeight->text().toInt() > 170)
        {
            ui->LE_CreateEndWeightInputIncorrect->show(); //show incorrect weight input label
            wrong = true;
        }
        if(ui->LE_CreateTableInputSteps->text().toInt() > 10 || ui->LE_CreateTableInputSteps->text().toInt() < 1)
        {
            ui->LE_CreateStepsInputIncorrect->show(); //show incorrect step  input label

            wrong = true;
        }
        if(wrong)
        {
            return;
        }
        ui->TB_CreateTable->setModel(CTtable->MakeTable(ui->LE_CreateTableInputWeight->text().toInt(),ui->LE_CreateTableInputSteps->text().toInt(), ui->LE_CreateTableInputEndWeight->text().toInt(),ui->LE_CreateTableInputLenght->text().toFloat(), this)); //create table
    }
}

void Quetelet_Index_Main::on_MainTab_currentChanged(int index)
{
    if(index == 3)
    {
        if(QMessageBox::question(this,"Quit","Are you sure you want to quit?", "No","Yes") == 1) //quit messagebox. quit if == 1
            exit(0);
        ui->MainTab->setCurrentIndex(0); //tab index sets to 0 if !1
    }

    Set_Quick_Result_Labels();
    Set_Create_Table_Incorrect_Labels();
    Clear_All_Inputs();
}

void Quetelet_Index_Main::OpenHelpWindow()
{
    HelpWindow->show(); //pop up help window
}

void Quetelet_Index_Main::Set_Quick_Result_Labels()
{
    ui->L_QuickCalcQueteletIndexResult->setText("No Result Available"); // Set label to default text
    ui->L_QuickCalcQueteletIndexResult->setStyleSheet("QLabel { color : red; border : none;}"); //Label changes to red color with no border
    ui->L_QuickCalcWeightStatusResult->setText("No Result Available");
    ui->L_QuickCalcWeightStatusResult->setStyleSheet("QLabel { color : red; border : none;}");
    ui->L_IncorrectInputWeightQuickCalcLenght->hide();
    ui->L_IncorrectInputWeightQuickCalcWeight->hide();
}

void Quetelet_Index_Main::Set_Create_Table_Incorrect_Labels()
{
    ui->LE_CreateWeightInputIncorrect->hide(); //hide  incorrect weight input label
    ui->LE_CreateLengthInputIncorrect->hide();
    ui->LE_CreateEndWeightInputIncorrect->hide();
    ui->LE_CreateStepsInputIncorrect->hide();
}

void Quetelet_Index_Main::Clear_All_Inputs()
{
    ui->LE_QuickCalcWeightInput->clear();
    ui->LE_QuickCalcLenghtInput->clear();
    ui->LE_CreateTableInputWeight->clear();
    ui->LE_CreateTableInputLenght->clear();
    ui->LE_CreateTableInputSteps->clear();
    ui->LE_CreateTableInputEndWeight->clear();
}

void Quetelet_Index_Main::on_BT_Help_clicked()
{
    HelpWindow->setTabIndex(0);
}
